package com.tianji.learning.service.Impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.tianji.api.client.course.CatalogueClient;
import com.tianji.api.client.course.CourseClient;
import com.tianji.api.client.learning.LearningClient;
import com.tianji.api.client.trade.TradeClient;
import com.tianji.api.dto.course.*;
import com.tianji.api.dto.leanring.LearningLessonDTO;
import com.tianji.common.domain.dto.PageDTO;
import com.tianji.common.domain.query.PageQuery;
import com.tianji.common.exceptions.BadRequestException;
import com.tianji.common.utils.AssertUtils;
import com.tianji.common.utils.BeanUtils;
import com.tianji.common.utils.CollUtils;
import com.tianji.common.utils.UserContext;
import com.tianji.learning.domain.po.LearningLesson;
import com.tianji.learning.domain.vo.LearningLessonVO;
import com.tianji.learning.enums.LessonStatus;
import com.tianji.learning.mapper.LearningLessonMapper;
import com.tianji.learning.service.ILearningLessonService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.print.attribute.standard.Media;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 学生课程表 服务实现类
 * </p>
 *
 * @author chengge
 * @since 2024-06-20
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class LearningLessonServiceImpl extends ServiceImpl<LearningLessonMapper, LearningLesson> implements ILearningLessonService {

    private final CourseClient courseClient;

    private final LearningClient learningClient;

    private final CatalogueClient catalogueClient;

    private final TradeClient tradeClient;




    /**
     * 批量新增课程
     *
     * @param userId
     * @param courseIds
     */
    @Override
    public void addLesson(Long userId, List<Long> courseIds) {
         // 1.查询课程有效期
        List<CourseSimpleInfoDTO> simpleInfoList = courseClient.getSimpleInfoList(courseIds);
        if (ObjectUtil.isEmpty(simpleInfoList)){
            log.error("课程信息为空,无法添加");
            return;
        }
        // 2.循环遍历，处理LearningLesson数据
        List<LearningLesson> lessonList = new ArrayList<>(simpleInfoList.size());
        for (CourseSimpleInfoDTO cour : simpleInfoList) {
            LearningLesson learningLesson = new LearningLesson();
            Integer validDuration = cour.getValidDuration();
            if (validDuration !=null && validDuration < 9999){
                learningLesson.setCreateTime(LocalDateTime.now());
                learningLesson.setExpireTime(LocalDateTime.now().plusMonths(validDuration));
            }
            learningLesson.setUserId(userId);
            learningLesson.setCourseId(cour.getId());
            lessonList.add(learningLesson);
        }
        // 3.批量新增
        saveBatch(lessonList);
    }

    /**
     * 批量删除课程
     *
     * @param userId
     * @param courseIds
     */
    @Override
    public void deleteLessons(Long userId, List<Long> courseIds) {
        // 1.查询课程有效期
        List<CourseSimpleInfoDTO> simpleInfoList = courseClient.getSimpleInfoList(courseIds);
        if (ObjectUtil.isEmpty(simpleInfoList)){
            log.error("课程信息为空,无法删除");
            return;
        }
        // 2.循环遍历，处理LearningLesson数据
        List<LearningLesson> lessonList = new ArrayList<>(simpleInfoList.size());
        for (CourseSimpleInfoDTO infoDTO : simpleInfoList) {
            LearningLesson learningLesson = new LearningLesson();
            learningLesson.setUserId(userId);
            learningLesson.setCourseId(infoDTO.getId());
            lessonList.add(learningLesson);
        }
        removeByIds(lessonList);

    }

    /**
     * 校验指定课程是否是课表中的有效课程
     *
     * @param courseId
     * @return
     */
    @Override
    public Long isLessonValid(Long courseId) {
        Long userId = UserContext.getUser();
        LearningLesson lesson = lambdaQuery()
                .eq(LearningLesson::getUserId, userId)
                .eq(LearningLesson::getCourseId, courseId)
                .one();
        if (ObjectUtil.isEmpty(lesson)){
            return null;
        }

        if (LocalDateTime.now().isBefore(lesson.getCreateTime()) && LocalDateTime.now().isAfter(lesson.getExpireTime())){
            return null;
        }
        return lesson.getCourseId();
    }

    /**
     * 统计课程学习人数
     *
     * @param courseId 课程id
     * @return 学习人数
     */
    @Override
    public Integer countLearningLessonByCourse(Long courseId) {
        //Integer integer = learningClient.countLearningLessonByCourse(courseId);
        Integer a = 0;
        CoursePurchaseInfoDTO purchaseInfoOfCourse = tradeClient.getPurchaseInfoOfCourse(courseId);
        if (ObjectUtil.isNotEmpty(purchaseInfoOfCourse)){
           a++;
        }
        return a;
    }


    /**
     * 分页查询课程
     *
     * @param
     * @return
     */
    @Override
    public PageDTO<LearningLessonVO> pagelesson(PageQuery query) {
        // 1.获取当前登录用户
        Long userId = UserContext.getUser();
        // 2.分页查询
        Page<LearningLesson> page = lambdaQuery()
                .eq(LearningLesson::getUserId, userId)
                .page(query.toMpPage("latest_learn_time", false));
        List<LearningLesson> records = page.getRecords();
        if (ObjectUtil.isEmpty(records)){
            return PageDTO.empty(page);
        }
        // 3.查询课程信息
        Map<Long, CourseSimpleInfoDTO> infoList = queryCourseSimpleInfoList(records);
        // 4.封装VO返回
        // 4.1.循环遍历，把LearningLesson转为VO
        List<LearningLessonVO> list = new ArrayList<>(records.size());
        for (LearningLesson r : records) {
            // 4.2.拷贝基础属性到vo
            LearningLessonVO vo = BeanUtils.copyBean(r, LearningLessonVO.class);
            // 4.3.获取课程信息，填充到vo
            CourseSimpleInfoDTO cours = infoList.get(r.getCourseId());
            vo.setCourseName(cours.getName());
            vo.setCourseCoverUrl(cours.getCoverUrl());
            vo.setSections(cours.getSectionNum());
            list.add(vo);
        }
        return PageDTO.of(page, list);
    }

    /**
     * 查询当前课程
     *
     * @param
     * @return
     */
    @Override
    public LearningLessonVO queryNowLesson() {

        Long userId = UserContext.getUser();
        LearningLesson lesson = lambdaQuery()
                .eq(LearningLesson::getUserId, userId)
                .eq(LearningLesson::getStatus, 1)
                .orderByDesc(LearningLesson::getLatestLearnTime)
                .last("limit 1")
                .one();
        if (ObjectUtil.isEmpty(lesson)){
            return null;
        }
        LearningLessonVO lessonVO = BeanUtil.toBean(lesson, LearningLessonVO.class);
        CourseFullInfoDTO courseInfoById = courseClient.getCourseInfoById(lessonVO.getCourseId(), false, false);
        if (ObjectUtil.isEmpty(courseInfoById)){
            log.error("课程信息为空,无法查询");
        }
        lessonVO.setCourseName(courseInfoById.getName());
        lessonVO.setCourseCoverUrl(courseInfoById.getCoverUrl());
        lessonVO.setSections(courseInfoById.getSectionNum());
        Integer validDuration = courseInfoById.getValidDuration();
        if (validDuration !=null && validDuration < 9999){
            lessonVO.setCreateTime(LocalDateTime.now());
            lessonVO.setExpireTime(LocalDateTime.now().plusMonths(validDuration));
        }
        Integer count = lambdaQuery().eq(LearningLesson::getUserId, userId).count();
        lessonVO.setCourseAmount(count);
        List<CataSimpleInfoDTO> cataSimpleInfoDTOS = catalogueClient
                .batchQueryCatalogue(CollUtils.singletonList(lesson.getLatestSectionId()));
        if (ObjectUtil.isNotEmpty(cataSimpleInfoDTOS)){
            CataSimpleInfoDTO cataSimpleInfoDTO = cataSimpleInfoDTOS.get(0);
            lessonVO.setLatestSectionName(cataSimpleInfoDTO.getName());
            lessonVO.setLatestSectionIndex(cataSimpleInfoDTO.getCIndex());
        }
        return lessonVO;
    }

    /**
     * 查询课程状态
     *
     * @param courseId
     * @return
     */
    @Override
    public LearningLesson queryCourseStatus(Long courseId) {
        return lambdaQuery()
                .eq(LearningLesson::getCourseId, courseId)
                .eq(LearningLesson::getUserId, UserContext.getUser())
                .one();
    }

    /**
     * 删除课程
     *
     * @param courseId
     */
    @Override
    public void deleteLesson(Long courseId) {
        log.info("删除课程,课程id:{}", courseId);
        Long userId = UserContext.getUser();
        if (ObjectUtil.isEmpty(courseId)){
            throw new BadRequestException("课程id不能为空");
        }
        lambdaUpdate().eq(LearningLesson::getUserId, userId)
                .eq(LearningLesson::getCourseId, courseId)
                .remove();
    }

    /**
     * 查询课程信息
     * @param records
     * @return
     */
    private Map<Long, CourseSimpleInfoDTO> queryCourseSimpleInfoList(List<LearningLesson> records) {
        Set<Long> collect = records.stream().map(LearningLesson::getCourseId).collect(Collectors.toSet());
        List<CourseSimpleInfoDTO> courseSimpleInfoDTOS = courseClient.getSimpleInfoList(collect);
        if (ObjectUtil.isEmpty(courseSimpleInfoDTOS)){
            throw new BadRequestException("课程信息为空");
        }
        Map<Long, CourseSimpleInfoDTO> collect1 = 
                courseSimpleInfoDTOS.stream()
                        .collect(Collectors.toMap(CourseSimpleInfoDTO::getId, c -> c));
        return collect1;
    }
}
